
from .Vector import Vector
class Matrix:
    """矩阵类"""
    def __init__(self,list2d):
        self._values = [row[:] for row in list2d]

    def __repr__(self):
        return "Matrix({})".format(self._values)
    __str__ = __repr__
    def share(self):
        """矩阵的行数和列数"""
        return len(self._values),len(self._values[0])
    def row_num(self):
        """矩阵的行数"""
        return self.share()[0]
    __len__ = row_num
    def col_num(self):
        """矩阵的列数"""
        return self.share()[1]
    def size(self):
        """矩阵的元素个数"""
        r,c = self.share()
        return r * c
    def row_vector(self,index):
        """矩阵的第index个行向量"""
        return Vector(self._values[index])
    def col_vector(self,index):
        """矩阵的第index个列向量"""
        return Vector([row[index] for row in self._values])

    def __getitem__(self, item):
        """返回均值第item处的元素"""
        r,c = item
        return self._values[r][c]
    @classmethod
    def zero(cls,r,c):
        """返回一个r行c列的零矩阵"""
        return cls([[0 for _ in range(c)] for _ in range(r)])
    def __add__(self, other):
        """矩阵的加法"""
        assert self.share() == other.share(),"矩阵的形状必须一致"
        return [[a+b for a,b in zip(self.row_vector(i),other.row_vector(i))]
                for i in range(self.row_num())]
    def __sub__(self, other):
        """矩阵的减法"""
        assert self.share() == other.share(), "矩阵的形状必须一致"
        return [[a - b for a, b in zip(self.row_vector(i), other.row_vector(i))]
                for i in range(self.row_num())]
    def __mul__(self, other):
        """矩阵的数量乘法matrix * other"""
        print(self.row_num())
        return [[other * e for e in self.row_vector(i)] for i in range(self.row_num())]
    def __rmul__(self, other):
        """矩阵的数量乘法 k * matrix"""
        return self * other
    def __truediv__(self, other):
        """矩阵的数量除法"""
        return 1/other * self
    def __pos__(self):
        """正矩阵"""
        return 1 * self
    def __neg__(self):
        """负矩阵"""
        return -1 * self

    def dot(self,othor):
        """矩阵的乘法"""
        if isinstance(othor,Vector):
            """矩阵和向量的乘法"""
            assert self.col_num() == len(othor),"矩阵的列数不等于向量的长度，无法计算"
            return Vector([self.row_vector(i).dot(othor) for i in range(self.row_num())])
        if isinstance(othor,Matrix):
            """矩阵和矩阵的乘法"""
            assert self.col_num() == othor.row_num(),"矩阵a的列数不等于矩阵b的行数，无法计算"
            return Matrix([[self.row_vector(i).dot(othor.col_vector(j)) for j in range(othor.col_num())] for i in range(self.row_num())])

    def T(self):
        """矩阵的转置"""
        return Matrix([[e for e in self.col_vector(i)] for i in range(self.col_num())])
    @classmethod
    def identity(cls,n):
        """单位矩阵"""
        m = [[0]*n for _ in range(n)]
        for i in range(n):
            m[i][i] = 1
        return cls(m)

